

#include "skeletalDrawing.h"
#include "renderer.h"
#include "control.h"
#include "boneActor.h"
#include "skeletalActor.h"
#include "spriteMeshLoader.h"


SkeletalDrawing::SkeletalDrawing(){


drawType=DRAW_PARTICLES;
skeletonName="NULL";
registerProperties();
}

SkeletalDrawing::~SkeletalDrawing(){}

void SkeletalDrawing::registerProperties(){

createMemberID("SKELETONNAME",&skeletonName,this);
ParticleSystem::registerProperties();
}

void SkeletalDrawing::setup(){

ParticleSystem::setup();
}


void SkeletalDrawing::singleSkin(int pID, int boneID){

    //simple single weighting
    particles[pID].color=Vector4f(boneID,0,0,0);
    particles[pID].secondaryColor=Vector4f(1.0,0,0,0);

    cout << "single skinning " << boneID << " " << pID << endl;

}

//here we get each particle with each bone!
void SkeletalDrawing::multiSkin(int pID, int *boneID){


        //the easy part - assign bone references
        particles[pID].color=Vector4f(max(boneID[0],0),max(boneID[1],0),max(boneID[2],0),max(boneID[3],0));
        //set weights to 0
        particles[pID].secondaryColor=Vector4f(0,0,0,0);

        //for every weight
        for (int i=0; i<4; i++){
            if (boneID[i]>-1){          //if it's actually a bone weight
                //calculate distance to particle
                Vector3f pLoc=Vector3f(particles[pID].location.x,particles[pID].location.y,particles[pID].location.z) + location;
                //here we should divide by the resulting Vector4f's .w to make sure we don't fuck up with scaling!
                //Vector4f bLocScale=(renderer->inverseCameraMatrix * bones[boneID[i]]->baseMatrix)* Vector4f(0.0,0.0,0.0,1.0);
                //Vector3f bLoc = Vector3f(bLocScale.x/bLocScale.w, bLocScale.y/bLocScale.w, bLocScale.y/bLocScale.z);

                Vector3f bLoc = (renderer->inverseCameraMatrix * bones[boneID[i]]->baseMatrix).getTranslation();
                float distance=(pLoc-bLoc).length();
                //apply the inverse-value ( 1/value) as weight
                particles[pID].secondaryColor[i]=max(1.0f - fabs(distance),0.0f);
            }
        }
        //normalize!
        particles[pID].secondaryColor.normalize();
}

void SkeletalDrawing::autoSkin(int pID, int boneID){

    Vector3f pLoc=Vector3f(particles[pID].location.x,particles[pID].location.y,particles[pID].location.z) + location;
    Vector3f bLoc=(renderer->inverseCameraMatrix * bones[boneID]->baseMatrix).getTranslation();
    float distance=(pLoc-bLoc).length();
    //simple circular weighting
    if (fabs(distance)<0.6){
        if (particles[pID].color.x>0.0){
            particles[pID].color=Vector4f(particles[pID].color.x,boneID,0,0);
            particles[pID].secondaryColor=Vector4f(fabs(distance)/0.6, (0.6-fabs(distance))/0.6 , 0, 0);
            particles[pID].secondaryColor.normalize();
            }
        else{
            particles[pID].color=Vector4f(boneID,0,0,0);
            particles[pID].secondaryColor=Vector4f(1.0,0,0,0);
            }
        }
    if (boneID==1)
        cout << fabs(distance) << endl;

}


void SkeletalDrawing::trigger(Actor * other){

}



void SkeletalDrawing::create(){renderer->addActor(this);}
